﻿namespace HuaWei.DAL.SqlClient
{
    using HuaWei.DAI;
    using System;
    using System.Collections;
    using System.Data;
    using System.Data.Common;
    using System.Runtime.InteropServices;

    public class MSSqlConcurrentProcessor : GInterface
    {
        private ConcurrentProcessType concurrentProcessType = ConcurrentProcessType.MANUAL_UPDATE;
        private Hashtable hash = new Hashtable();
        private IDbTransaction idbTransaction = null;
        private string str = "ColumnName";
        private string str1 = "IsKey";
        private string str2 = "ColumnSize";

        private bool method(IDbConnection idbConnection, DataRow dataRow, StatementType statementType)
        {
            IDataReader reader = null;
            idbConnection.CreateCommand();
            ArrayList arrayList = null;
            int num = 0;
            bool flag = true;
            string str = this.method9(idbConnection, dataRow, out arrayList);
            reader = this.method8(idbConnection, str, arrayList);
            if (reader.Read())
            {
                num = reader.GetInt32(0);
            }
            reader.Close();
            if (num <= 0)
            {
                if (statementType != StatementType.Delete)
                {
                    dataRow.RowError = "该行已经被删除！";
                    flag = false;
                }
                return flag;
            }
            dataRow.RowError = "该行已经被修改！";
            return flag;
        }

        private bool method1(IDbConnection idbConnection, DataRow dataRow, StatementType statementType)
        {
            IDataReader reader = null;
            idbConnection.CreateCommand();
            ArrayList arrayList = null;
            bool flag = false;
            bool flag2 = true;
            string str = this.method10(idbConnection, dataRow, out arrayList);
            reader = this.method8(idbConnection, str, arrayList);
            if (reader.Read())
            {
                if (statementType != StatementType.Delete)
                {
                    for (int i = 0; i < reader.FieldCount; i++)
                    {
                        string name = reader.GetName(i);
                        if (dataRow.Table.Columns.Contains(name))
                        {
                            dataRow[name] = reader.GetValue(i);
                        }
                    }
                }
            }
            else
            {
                flag = true;
            }
            if (flag)
            {
                if (statementType != StatementType.Delete)
                {
                    dataRow.RowError = "该行已经被删除！";
                    flag2 = false;
                }
            }
            else
            {
                dataRow.RowError = "该行已经被修改（获取最新数据）！";
            }
            reader.Close();
            return flag2;
        }

        private string method10(IDbConnection idbConnection, DataRow dataRow, out ArrayList arrayList)
        {
            return (("select * from [" + dataRow.Table.TableName + "] where 1=1 ") + this.method13(idbConnection, dataRow, out arrayList));
        }

        private string method11(IDbConnection idbConnection, DataRow dataRow, out ArrayList arrayList)
        {
            string tableName = dataRow.Table.TableName;
            string str2 = this.method13(idbConnection, dataRow, out arrayList);
            return (" if (select count(*)     from [" + tableName + "] where 1=1 " + str2 + " )>0  begin     delete from [" + tableName + "] where 1=1 " + str2 + " end");
        }

        private string method12(IDbConnection idbConnection, DataRow dataRow, out ArrayList arrayList)
        {
            string tableName = dataRow.Table.TableName;
            string str2 = this.method13(idbConnection, dataRow, out arrayList);
            if (arrayList == null)
            {
                arrayList = new ArrayList();
            }
            string str3 = " if(select count(*)    from [" + tableName + "] where 1=1 " + str2 + " )>0  begin     update [" + tableName + "] set ";
            bool flag = true;
            foreach (DataColumn column in dataRow.Table.Columns)
            {
                if (!this.method14(idbConnection, tableName, column.ColumnName))
                {
                    int num = this.method18(idbConnection, tableName, column.ColumnName);
                    IDbDataParameter parameter = idbConnection.CreateCommand().CreateParameter();
                    parameter.DbType = SqlDataTypeConvert.GetDbType(column.DataType);
                    parameter.Size = num;
                    parameter.ParameterName = "@" + column.ColumnName;
                    parameter.Value = dataRow[column];
                    arrayList.Add(parameter);
                    if (!flag)
                    {
                        str3 = str3 + ",";
                    }
                    str3 = str3 + column.ColumnName + "=@" + column.ColumnName;
                    flag = false;
                }
            }
            return ((str3 + " where 1=1 " + str2) + " end");
        }

        private string method13(IDbConnection idbConnection, DataRow dataRow, out ArrayList arrayList)
        {
            string str = "";
            arrayList = new ArrayList();
            ArrayList list = this.method15(idbConnection, dataRow.Table.TableName);
            if ((list != null) && (list.Count > 0))
            {
                foreach (string str2 in list)
                {
                    if (dataRow.Table.Columns.Contains(str2))
                    {
                        string str3 = str;
                        str = str3 + " and [" + str2 + "]=@" + str2;
                        IDbDataParameter parameter = idbConnection.CreateCommand().CreateParameter();
                        parameter.DbType = SqlDataTypeConvert.GetDbType(dataRow.Table.Columns[str2].DataType);
                        parameter.ParameterName = "@" + str2;
                        parameter.Size = this.method18(idbConnection, dataRow.Table.TableName, str2);
                        parameter.Value = dataRow[str2, DataRowVersion.Original];
                        arrayList.Add(parameter);
                    }
                }
            }
            return str;
        }

        private bool method14(IDbConnection idbConnection, string str3, string str4)
        {
            bool flag = false;
            ArrayList list = this.method15(idbConnection, str3);
            if ((list != null) && list.Contains(str4))
            {
                flag = true;
            }
            return flag;
        }

        private ArrayList method15(IDbConnection idbConnection, string str3)
        {
            DataTable table = null;
            if (this.hash.Contains(str3))
            {
                table = this.hash[str3] as DataTable;
            }
            else
            {
                table = this.method17(idbConnection, str3);
                this.hash.Add(str3, table);
            }
            return this.method16(table);
        }

        private ArrayList method16(DataTable dataTable)
        {
            ArrayList list = new ArrayList();
            if (((((dataTable != null) && (dataTable.Rows != null)) && ((dataTable.Rows.Count > 0) && dataTable.Columns.Contains(this.str))) && (dataTable.Columns.Contains(this.str1) && (dataTable.Columns[this.str].DataType == typeof(string)))) && (dataTable.Columns[this.str1].DataType == typeof(bool)))
            {
                foreach (DataRow row in dataTable.Rows)
                {
                    if ((bool) row[this.str1])
                    {
                        string str = row[this.str] as string;
                        list.Add(str);
                    }
                }
            }
            return list;
        }

        private DataTable method17(IDbConnection idbConnection, string str3)
        {
            IDbCommand command = null;
            IDataReader reader = null;
            DataTable schemaTable = null;
            new ArrayList();
            command = idbConnection.CreateCommand();
            command.CommandText = "select * from [" + str3 + "]";
            if ((idbConnection.State == ConnectionState.Closed) || (idbConnection.State == ConnectionState.Broken))
            {
                idbConnection.Open();
            }
            if (this.idbTransaction != null)
            {
                command.Transaction = this.idbTransaction;
            }
            reader = command.ExecuteReader(CommandBehavior.KeyInfo | CommandBehavior.SchemaOnly);
            schemaTable = reader.GetSchemaTable();
            reader.Close();
            return schemaTable;
        }

        private int method18(IDbConnection idbConnection, string str3, string str4)
        {
            DataTable table = null;
            if (this.hash.Contains(str3))
            {
                table = this.hash[str3] as DataTable;
            }
            else
            {
                table = this.method17(idbConnection, str3);
                this.hash.Add(str3, table);
            }
            return (int) table.Select(this.str + "='" + str4 + "'")[0][this.str2];
        }

        private bool method2(IDbConnection idbConnection, DataRow dataRow, StatementType statementType)
        {
            switch (statementType)
            {
                case StatementType.Select:
                    return this.method5(idbConnection, dataRow);

                case StatementType.Insert:
                    return this.method6(idbConnection, dataRow);

                case StatementType.Update:
                    return this.method4(idbConnection, dataRow);

                case StatementType.Delete:
                    return this.method3(idbConnection, dataRow);
            }
            return false;
        }

        private bool method3(IDbConnection idbConnection, DataRow dataRow)
        {
            ArrayList arrayList = null;
            string str = this.method11(idbConnection, dataRow, out arrayList);
            this.method7(idbConnection, str, arrayList);
            return true;
        }

        private bool method4(IDbConnection idbConnection, DataRow dataRow)
        {
            bool flag = true;
            ArrayList arrayList = null;
            string str = this.method12(idbConnection, dataRow, out arrayList);
            if (this.method7(idbConnection, str, arrayList) <= 0)
            {
                dataRow.RowError = "该行已经被删除！";
                flag = false;
            }
            return flag;
        }

        private bool method5(IDbConnection idbConnection, DataRow dataRow)
        {
            return false;
        }

        private bool method6(IDbConnection idbConnection, DataRow dataRow)
        {
            return false;
        }

        private int method7(IDbConnection idbConnection, string str3, ArrayList arrayList)
        {
            IDbCommand command = idbConnection.CreateCommand();
            command.CommandText = str3;
            if ((idbConnection.State == ConnectionState.Closed) || (idbConnection.State == ConnectionState.Broken))
            {
                idbConnection.Open();
            }
            if (this.idbTransaction != null)
            {
                command.Transaction = this.idbTransaction;
            }
            if ((arrayList != null) && (arrayList.Count > 0))
            {
                foreach (IDbDataParameter parameter in arrayList)
                {
                    if (!command.Parameters.Contains(parameter))
                    {
                        command.Parameters.Add(parameter);
                    }
                }
            }
            return command.ExecuteNonQuery();
        }

        private IDataReader method8(IDbConnection idbConnection, string str3, ArrayList arrayList)
        {
            IDbCommand command = idbConnection.CreateCommand();
            command.CommandText = str3;
            if ((idbConnection.State == ConnectionState.Closed) || (idbConnection.State == ConnectionState.Broken))
            {
                idbConnection.Open();
            }
            if (this.idbTransaction != null)
            {
                command.Transaction = this.idbTransaction;
            }
            if ((arrayList != null) && (arrayList.Count > 0))
            {
                foreach (IDbDataParameter parameter in arrayList)
                {
                    if (!command.Parameters.Contains(parameter))
                    {
                        command.Parameters.Add(parameter);
                    }
                }
            }
            return command.ExecuteReader();
        }

        private string method9(IDbConnection idbConnection, DataRow dataRow, out ArrayList arrayList)
        {
            return (("select count(*) as Num from [" + dataRow.Table.TableName + "] where 1=1 ") + this.method13(idbConnection, dataRow, out arrayList));
        }

        public void Process(RowUpdatedEventArgs e)
        {
            if ((e.Status == UpdateStatus.ErrorsOccurred) && (e.Errors.GetType() == typeof(DBConcurrencyException)))
            {
                DataRow dataRow = e.Row;
                this.idbTransaction = e.Command.Transaction;
                switch (this.concurrentProcessType)
                {
                    case ConcurrentProcessType.CONTINUE:
                        this.method(e.Command.Connection, e.Row, e.StatementType);
                        e.Status = UpdateStatus.Continue;
                        break;

                    case ConcurrentProcessType.CONTINUE_GETNEWDATA:
                        this.method1(e.Command.Connection, dataRow, e.StatementType);
                        e.Status = UpdateStatus.Continue;
                        break;

                    case ConcurrentProcessType.MANUAL_UPDATE:
                        if (this.method2(e.Command.Connection, dataRow, e.StatementType))
                        {
                            e.Status = UpdateStatus.Continue;
                        }
                        break;
                }
            }
        }

        public ConcurrentProcessType ProcessType
        {
            get
            {
                return this.concurrentProcessType;
            }
            set
            {
                this.concurrentProcessType = value;
            }
        }
    }
}

